/*-
 *  Copyright (C) 2009 Peter Baldwin   
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.peterbaldwin.client.android.sms2email;

import java.text.MessageFormat;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.MailTo;
import android.net.ParseException;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

// TODO: Implement formatted message preview
public class MessageCompose extends Activity implements View.OnClickListener,
		TextWatcher, SharedPreferences.OnSharedPreferenceChangeListener {

	private static final int MENU_EDIT = 1;

	private static final String STATE_TO = "to";
	private static final String STATE_SUBJECT = "subject";
	private static final String STATE_MESSAGE_CONTENT = "messageContent";

	private AutoCompleteTextView mEditTo;
	private EditText mEditSubject;
	private EditText mEditBody;
	private TextView mTextRemaining;
	private Button mButtonSend;
	private Button mButtonDiscard;
	private EmailAddressAdapter mAdapter;

	private SharedPreferences mPreferences;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.message_compose);
		mEditTo = (AutoCompleteTextView) findViewById(R.id.to);
		mEditSubject = (EditText) findViewById(R.id.subject);
		mEditBody = (EditText) findViewById(R.id.message_content);
		mTextRemaining = (TextView) findViewById(R.id.text_remaining);
		mButtonSend = (Button) findViewById(R.id.button_send);
		mButtonDiscard = (Button) findViewById(R.id.button_discard);

		mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
		mPreferences.registerOnSharedPreferenceChangeListener(this);

		mAdapter = new EmailAddressAdapter(this);
		mEditTo.setAdapter(mAdapter);

		mEditTo.addTextChangedListener(this);
		mEditSubject.addTextChangedListener(this);
		mEditBody.addTextChangedListener(this);
		mButtonSend.setOnClickListener(this);
		mButtonDiscard.setOnClickListener(this);

		Intent intent = getIntent();
		String action = intent.getAction();
		Uri data = intent.getData();
		String type = intent.getType();
		if (savedInstanceState != null) {
			String to = savedInstanceState.getString(STATE_TO);
			String subject = savedInstanceState.getString(STATE_SUBJECT);
			String messageContent = savedInstanceState
					.getString(STATE_MESSAGE_CONTENT);
			mEditTo.setText(to);
			mEditSubject.setText(subject);
			mEditBody.setText(messageContent);
		} else if (Intent.ACTION_SENDTO.equals(action)) {
			if (data != null) {
				try {
					MailTo mailTo = MailTo.parse(String.valueOf(data));
					String to = mailTo.getTo();
					String subject = mailTo.getSubject();
					String body = mailTo.getBody();
					if (to != null) {
						mEditTo.setText(to);
					}
					if (subject != null) {
						mEditSubject.setText(subject);
					}
					if (body != null) {
						mEditBody.setText(body);
					}
				} catch (ParseException e) {
					// Continue with blank message
				}
			}
		} else if (Intent.ACTION_SEND.equals(action)
				&& "text/plain".equals(type)) {
			String[] emails = intent.getStringArrayExtra(Intent.EXTRA_EMAIL);
			String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
			String text = intent.getStringExtra(Intent.EXTRA_TEXT);
			if (emails != null && emails.length != 0) {
				// Only a single email address is supported
				String email = emails[0];
				mEditTo.setText(email);
			}
			if (subject != null) {
				mEditSubject.setText(subject);
			}
			if (text != null) {
				mEditBody.setText(text);
			}
		} else {
			// TODO: Handle Intent.ACTION_SEND + type "image/*" if any carriers
			// support MMS to email + attachment
		}
		
		updateRemaining();
	}
	
	private void updateRemaining() {
		String message = getMessage();
		int remaining = 140 - message.length();
		String template = getString(R.string.text_remaining);
		Object[] objects = { new Integer(remaining) };
		mTextRemaining.setText(MessageFormat.format(template, objects));
	}

	@Override
	public void afterTextChanged(Editable s) {
		updateRemaining();
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		if (key.equals(EditPreferences.PREF_FORMAT)) {
			updateRemaining();
		}
	}

	private static String getString(EditText view) {
		Editable text = view.getText();
		return String.valueOf(text);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		String to = getString(mEditTo);
		String subject = getString(mEditSubject);
		String messageContent = getString(mEditBody);
		outState.putString(STATE_TO, to);
		outState.putString(STATE_SUBJECT, subject);
		outState.putString(STATE_MESSAGE_CONTENT, messageContent);
	}

	private String getDestinationAddress() {
		String number = mPreferences.getString(EditPreferences.PREF_NUMBER,
				EditPreferences.DEFAULT_PREF_NUMBER);
		if (number.trim().length() == 0) {
			return null;
		}
		String destinationAddress = number;
		String email = getString(mEditTo);
		destinationAddress = destinationAddress.replace("{email}", email);
		return destinationAddress;
	}

	private String getMessage() {
		String format = mPreferences.getString(EditPreferences.PREF_FORMAT,
				EditPreferences.DEFAULT_PREF_FORMAT);
		String email = getString(mEditTo);
		String subject = getString(mEditSubject);
		String body = getString(mEditBody);
		String text = format;
		text = text.replace("{email}", email);
		text = text.replace("{subject}", subject);
		text = text.replace("{body}", body);
		return text;
	}

	private void onSend() {
		String destinationAddress = getDestinationAddress();
		String text = getMessage();
		
		if (destinationAddress == null) {
			// TODO: Inform user that they must enter a number
			Intent intent = new Intent(this, EditPreferences.class);
			startActivity(intent);
		}

		SmsManager manager = SmsManager.getDefault();
		String scAddress = null; // Use default SMSC
		PendingIntent sentIntent = PendingIntent.getBroadcast(this, 0,
				new Intent(this, DeliveryReportReceiver.class), 0);
		PendingIntent deliveryIntent = null;

		Toast toast = Toast.makeText(this, R.string.notify_sending,
				Toast.LENGTH_SHORT);
		toast.show();
		manager.sendTextMessage(destinationAddress, scAddress, text,
				sentIntent, deliveryIntent);
		finish();
	}

	private void onDiscard() {
		finish();
	}

	@Override
	public void onClick(View view) {
		if (view == mButtonSend) {
			onSend();
		} else if (view == mButtonDiscard) {
			onDiscard();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuItem item = menu.add(0, MENU_EDIT, 0, R.string.menu_preferences);
		item.setIcon(android.R.drawable.ic_menu_preferences);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_EDIT:
			Intent intent = new Intent(this, EditPreferences.class);
			startActivity(intent);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
}